package com.mdd.front.controller;


import cn.hutool.core.lang.UUID;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.mdd.common.constant.GlobalConstant;
import com.mdd.common.core.AjaxResult;
import com.mdd.common.entity.album.Album;
import com.mdd.common.entity.code.CouponCode;
import com.mdd.common.entity.salesman.Salesman;
import com.mdd.common.entity.salesman.SalesmanGoogs;
import com.mdd.common.enums.AlbumEnum;
import com.mdd.common.exception.OperateException;
import com.mdd.common.mapper.coupon.CouponCodeMapper;
import com.mdd.common.mapper.googs.SalesmanGoogsMapper;
import com.mdd.common.mapper.salesman.SalesmanMapper;
import com.mdd.common.plugin.storage.StorageDriver;
import com.mdd.common.utils.RedisUtil;
import com.mdd.front.LikeFrontThreadLocal;
import com.mdd.front.service.album.IAlbumService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.util.MimeTypeUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/generation")
@Slf4j
public class QRCodeGenerationController {

	@Resource
	private RestTemplate restTemplate;

	@Value("${wx.qr.generationUrl}")
	private String url;

	@Value("${wx.qr.accessToken}")
	private String accessTokenUrl;

	@Value("${wx.app.appId}")
	private String appId;

	@Value("${wx.app.secret}")
	private String appSecret;

	@Resource
	private IAlbumService iAlbumService;

	@Resource
	private SalesmanMapper salesmanMapper;

	@Value("${wx.qr.envProfile}")
	private String envProfile;
    @Resource
    private SalesmanGoogsMapper salesmanGoogsMapper;
    @Resource
    private CouponCodeMapper couponCodeMapper;

	/**
	 * 获取用户邀请二维码
	 */
	@GetMapping("/invitationCode")
	public String generateQRCode(@RequestParam(value = "width", required = false, defaultValue = "430") Integer width) {
		// 首先需要获取accessToken， 获取了之后需要获取图片，如果没有生成推荐码，则生成推荐码
		Integer userId = LikeFrontThreadLocal.getUserId();
		String fileName = "推销码" + userId + ".png";
		HashMap<String, Object> mapUser = new HashMap<>();
		mapUser.put("user_id", userId);
		mapUser.put("is_delete", 0);
		List<Salesman> salesmen = salesmanMapper.selectByMap(mapUser);
		if (salesmen == null || salesmen.isEmpty()) {
			throw new OperateException("你不是该推销员，不能拥有推销码");
		}

		LambdaQueryWrapper<Album> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(true, Album::getCid, 3);
		queryWrapper.eq(true, Album::getName, fileName);
		queryWrapper.eq(true, Album::getIsDelete, GlobalConstant.NOT_DELETE);

		Album one = iAlbumService.getOne(queryWrapper);
		if (Objects.isNull(one)) {
			try {
				StringBuilder sendUrl = new StringBuilder(url);
				Map<String, Object> requestBody = new HashMap<>();
				requestBody.put("page", "pages/login/login");  // 设置二维码跳转的地址
				requestBody.put("scene", "userId=" + userId);  // 设置推荐人的id
				requestBody.put("width", width.toString());     // 设置宽度
				requestBody.put("auto_color", false);
				requestBody.put("env_version", envProfile);
				Map<String, String> color = new HashMap<>();
				color.put("r", "125");
				color.put("g", "82");
				color.put("b", "132");
				requestBody.put("line_color", color);
				HttpHeaders headers = new HttpHeaders();
				headers.setContentType(MediaType.APPLICATION_JSON);
				HttpEntity<Map<String, Object>> httpEntity = new HttpEntity<Map<String, Object>>(requestBody, headers);
				String accessTokenKey = "wx:accessToken";
				// 获取wx的accessToken，如果没有则调用接口获取
				String getAccessTokenUrl = accessTokenUrl + "?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret;
				String forObject = restTemplate.getForObject(getAccessTokenUrl, String.class);
				JSONObject jsonObject = JSONUtil.parseObj(forObject);
				String accessToken = jsonObject.getStr("access_token");
				sendUrl.append("?access_token=" + accessToken);
				byte[] result = restTemplate.postForObject(sendUrl.toString(), httpEntity, byte[].class);
				MultipartFile multipartFile = new MockMultipartFile(fileName, fileName, MimeTypeUtils.IMAGE_PNG_VALUE, result);
				StorageDriver storageDriver = new StorageDriver();
				Map<String, Object> map = storageDriver.upload(multipartFile, "image", AlbumEnum.IMAGE.getCode());
				Map<String, String> album = new LinkedHashMap<>();
				album.put("aid", "0");
				// 设置为3，代表推销码目录
				album.put("cid", "3");
				album.put("type", String.valueOf(AlbumEnum.IMAGE.getCode()));
				album.put("size", map.get("size").toString());
				album.put("ext", map.get("ext").toString());
				album.put("url", map.get("url").toString());
				album.put("name", map.get("name").toString());
				iAlbumService.albumAdd(album);
				return album.get("url");
			} catch (Exception e) {
				log.error(e.toString());
			}
		}
		return one.getUri();
	}


	/**
	 * 该方法是获取拉新订单的二维码
	 * @param width 宽度
	 * @param goodsId 服务id
	 * @return 二维码地址
	 */
	@GetMapping("/generateScanPay")
	public String generateScanPay(@RequestParam(value = "width", required = false, defaultValue = "430") Integer width,
								  @RequestParam(value = "goodsId") Integer goodsId) {
// 首先需要获取accessToken， 获取了之后需要获取图片，如果没有生成推荐码，则生成推荐码
		Integer userId = LikeFrontThreadLocal.getUserId();
		String fileName = "拉新码" + userId + goodsId + ".png";
		isSalesman(userId, goodsId);
		LambdaQueryWrapper<Album> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(true, Album::getCid, GlobalConstant.QR_SCAN_PAY);
		queryWrapper.eq(true, Album::getName, fileName);
		queryWrapper.eq(true, Album::getIsDelete, GlobalConstant.NOT_DELETE);

		Album one = iAlbumService.getOne(queryWrapper);
		if (Objects.isNull(one)) {
			try {
				StringBuilder sendUrl = new StringBuilder(url);
				Map<String, Object> requestBody = new HashMap<>();
				requestBody.put("page", "pages/goods/index");  // 设置二维码跳转的地址
				requestBody.put("scene", "userId=" + userId + "&id=" + goodsId + "&scanCode=1");  // 设置拉新人的id
				requestBody.put("width", width.toString());     // 设置宽度
				requestBody.put("auto_color", false);
				requestBody.put("env_version", envProfile);
				Map<String, String> color = new HashMap<>();
				color.put("r", "125");
				color.put("g", "82");
				color.put("b", "132");
				requestBody.put("line_color", color);
				HttpHeaders headers = new HttpHeaders();
				headers.setContentType(MediaType.APPLICATION_JSON);
				HttpEntity<Map<String, Object>> httpEntity = new HttpEntity<Map<String, Object>>(requestBody, headers);
				String accessTokenKey = "wx:accessToken";
				// 获取wx的accessToken，如果没有则调用接口获取
				String getAccessTokenUrl = accessTokenUrl + "?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret;
				String forObject = restTemplate.getForObject(getAccessTokenUrl, String.class);
				JSONObject jsonObject = JSONUtil.parseObj(forObject);
				String accessToken = jsonObject.getStr("access_token");
				sendUrl.append("?access_token=" + accessToken);
				byte[] result = restTemplate.postForObject(sendUrl.toString(), httpEntity, byte[].class);
				MultipartFile multipartFile = new MockMultipartFile(fileName, fileName, MimeTypeUtils.IMAGE_PNG_VALUE, result);
				StorageDriver storageDriver = new StorageDriver();
				Map<String, Object> map = storageDriver.upload(multipartFile, "image", AlbumEnum.IMAGE.getCode());
				Map<String, String> album = new LinkedHashMap<>();
				album.put("aid", "0");
				// 设置为66，代表拉新订单码
				album.put("cid", GlobalConstant.QR_SCAN_PAY + "");
				album.put("type", String.valueOf(AlbumEnum.IMAGE.getCode()));
				album.put("size", map.get("size").toString());
				album.put("ext", map.get("ext").toString());
				album.put("url", map.get("url").toString());
				album.put("name", map.get("name").toString());
				iAlbumService.albumAdd(album);
				return album.get("url");
			} catch (Exception e) {
				log.error(e.toString());
			}
		}
		return one.getUri();
	}

	@GetMapping("/getCacheCode")
	public Object getCacheCode(@RequestParam("code") String code) {
		return AjaxResult.success(RedisUtil.get(code));
	}

	/**
	 * 该方法是获取推销员免费拉新的图片地址，最多10张， 低于4张则生成到10张
	 * @param goodsId 服务id
	 * @param goodsSpecificationId 规格id
	 * @return 返回二维码地址
	 */
	@GetMapping("/generateGratisQR")
	public List<String> generateGratisQR(@RequestParam(value = "width", required = false, defaultValue = "430") Integer width,
								  @RequestParam(value = "goodsId") Integer goodsId,
								   @RequestParam(value = "goodsSpecificationId") Integer goodsSpecificationId) {
// 首先需要获取accessToken， 获取了之后需要获取图片，如果没有生成推荐码，则生成推荐码
		Integer userId = LikeFrontThreadLocal.getUserId();
		String fileName = "免费拉新码编号" + userId + "_" + goodsSpecificationId + "_";
		isSalesman(userId, goodsId);
		LambdaQueryWrapper<Album> queryWrapper = new LambdaQueryWrapper<>();
		queryWrapper.eq(true, Album::getCid, GlobalConstant.QR_GRATIS_PAY);
		queryWrapper.like(true, Album::getName, fileName);
		queryWrapper.eq(true, Album::getIsDelete, GlobalConstant.NOT_DELETE);
		List<Album> list = iAlbumService.list(queryWrapper);
		List<String> dataMap = new ArrayList<>();
		if (list.size() <= 4) {
			for(int i = list.size();i < 10; i++) {
				try {
					fileName = "免费拉新码编号" + userId + "_" + goodsSpecificationId + "_";
					CouponCode couponCode = new CouponCode();
					couponCode.setCouponId(GlobalConstant.QR_ID);
					couponCode.setIsUse(0);
					String uuid = UUID.randomUUID(true).toString(true).substring(3, 18);
					couponCode.setCouponCode(uuid);

					StringBuilder sendUrl = new StringBuilder(url);
					Map<String, Object> requestBody = new HashMap<>();
					requestBody.put("page", "pages/order_buy/index");  // 设置二维码跳转的地址
					String value = "userId=" + userId + "&goodsId=" + goodsId
							+ "&goodsNum=" + 1 + "&goodsSpecificationId=" + goodsSpecificationId
							+ "&qrCode=" + uuid;
					requestBody.put("scene", uuid);  // 设置免费拉新人的id和优惠code
					RedisUtil.set(uuid, value);
					requestBody.put("width", width.toString());     // 设置宽度
					requestBody.put("auto_color", false);
					requestBody.put("env_version", envProfile);
					Map<String, String> color = new HashMap<>();
					color.put("r", "125");
					color.put("g", "82");
					color.put("b", "132");
					requestBody.put("line_color", color);
					HttpHeaders headers = new HttpHeaders();
					headers.setContentType(MediaType.APPLICATION_JSON);
					HttpEntity<Map<String, Object>> httpEntity = new HttpEntity<Map<String, Object>>(requestBody, headers);
					String accessTokenKey = "wx:accessToken";
					// 获取wx的accessToken，如果没有则调用接口获取
					String getAccessTokenUrl = accessTokenUrl + "?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret;
					String forObject = restTemplate.getForObject(getAccessTokenUrl, String.class);
					JSONObject jsonObject = JSONUtil.parseObj(forObject);
					String accessToken = jsonObject.getStr("access_token");
					sendUrl.append("?access_token=" + accessToken);
					byte[] result = restTemplate.postForObject(sendUrl.toString(), httpEntity, byte[].class);
					fileName = fileName + uuid + ".png";  // 重新设置图片名称
					MultipartFile multipartFile = new MockMultipartFile(fileName, fileName, MimeTypeUtils.IMAGE_PNG_VALUE, result);
					StorageDriver storageDriver = new StorageDriver();
					Map<String, Object> map = storageDriver.upload(multipartFile, "image", AlbumEnum.IMAGE.getCode());
					Map<String, String> album = new LinkedHashMap<>();
					album.put("aid", "0");
					// 设置为55，代表免费商品订单码
					album.put("cid", GlobalConstant.QR_GRATIS_PAY + "");
					album.put("type", String.valueOf(AlbumEnum.IMAGE.getCode()));
					album.put("size", map.get("size").toString());
					album.put("ext", map.get("ext").toString());
					album.put("url", map.get("url").toString());
					album.put("name", map.get("name").toString());
					couponCode.setImageId(iAlbumService.albumAdd(album));
					// return album.get("url");
					couponCodeMapper.insert(couponCode);
					log.info("优惠券团购： "  + map.get("url"));
					dataMap.add(map.get("url").toString());
				} catch (Exception e) {
					e.printStackTrace();
					log.error(e.toString());
				}
			}
		} else {
			dataMap = list.stream().map(Album::getUri).collect(Collectors.toList());
		}
		return dataMap;
	}

	private void isSalesman(Integer userId, Integer goodsId) {
		HashMap<String, Object> mapUser = new HashMap<>();
		mapUser.put("user_id", userId);
		mapUser.put("is_delete", 0);
		List<Salesman> salesmen = salesmanMapper.selectByMap(mapUser);
		if (salesmen == null || salesmen.isEmpty()) {
			throw new OperateException("你不是推销员，不能生成拉新订单");
		}
		LambdaQueryWrapper<SalesmanGoogs> salesmanGoogsLambdaQueryWrapper = new LambdaQueryWrapper<>();
		salesmanGoogsLambdaQueryWrapper.eq(SalesmanGoogs::getSalesmanId, salesmen.get(0).getId());
		salesmanGoogsLambdaQueryWrapper.eq(SalesmanGoogs::getProductId, goodsId);
		SalesmanGoogs salesmanGoogs = salesmanGoogsMapper.selectOne(salesmanGoogsLambdaQueryWrapper);
		if(Objects.isNull(salesmanGoogs)) {
			throw new OperateException("你当前没有该服务");
		}
	}

}
